home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / flowcntl.zip / FLOWCNTL.ASM < prev    next >
Assembly Source File  |  1984-12-18  |  4KB  |  165 lines

  1.     page    60,132
  2.     title    flowcntl - alter serial port com1 to use ^S/^Q handshaking
  3.  
  4. ;   By: Bruce Walker
  5. ; Date: Oct 23, 1984
  6. ;  Mod: Oct 25, 1984
  7. ;
  8. ; I hereby give permission to do any damn thing you want with this program
  9. ; provided you don't try to blame me for anything naughty it might do.
  10. ; It would be nice if you left this title comment block intact if you
  11. ; modify it, but feel free to add your own name to the blameless list.
  12. ; If you manage to remove any restrictions or otherwise improve it, please
  13. ; repost the result.
  14. ;
  15. ; How to Use (and What it Does):
  16. ;
  17. ;    Set up a batch file (or edit AUTOEXEC.BAT) with a line to set the mode
  18. ;    of COM1: to the required baud rate, and follow it with a line to invoke
  19. ;    this program. eg:
  20. ;
  21. ;        mode com1:9600,N,8,1
  22. ;        flowcntl
  23. ;
  24. ;    which will drive a 9600 baud, no parity, eight data-bit and one stop
  25. ;    bit serial printer.
  26. ;
  27. ;    The program then loads itself into memory (where it remains until you
  28. ;    reboot) and intercepts any conversations with COM1 and controls the
  29. ;    output flow according to the time-honoured ^S/^Q (DC3/DC1 or XON/XOFF)
  30. ;    protocol.
  31. ;
  32. ;    To control a serial printer, add a line to redirect the LPT1: device
  33. ;    to the COM1: device. eg:
  34. ;
  35. ;        mode LPT1:=COM1:
  36. ;
  37. ;    Now, if you invoke the PRINT command, and hit return when it asks you
  38. ;    what device to use for output, your serial printer will buzz away
  39. ;    happily to itself, while DOS thinks it's talking to a parallel Epson.
  40. ;
  41. ;
  42. ; How To Make:
  43. ;
  44. ;    Do something like the following:
  45. ;
  46. ;        masm flowcntl,,,nul;
  47. ;        link flowcntl,,nul;
  48. ;        exe2bin flowcntl flowcntl.com
  49. ;        del flowcntl.exe
  50. ;        del flowcntl.obj
  51. ;
  52. ;    It has been tested with PC-DOS 2.1 and with printers up to 9600 baud.
  53. ;    Because it operates at the BIOS level, it should also work with early
  54. ;    DOS's like DOS 1.1 .
  55. ;
  56. ; Limitations:
  57. ;
  58. ;    - this is an unabashed hack (it is NOT a "device driver", it should be).
  59. ;    - uses ("user-definable") interrupt 60H; this may conflict with
  60. ;      someone, somewhere.
  61. ;    - only uses com1:.
  62. ;    - does not work with BIOS-internal routines such as "PRINT_SCREEN" (I
  63. ;      am not sure why) therefore the "<SHIFT> PrtSc" button should not be
  64. ;      pressed.
  65. ;    - as a consequence of the above, Wordstar (for example) does not work
  66. ;      with this code so don't invoke it when using Wordstar, just use WS's
  67. ;      WINSTALL program to set up their internal serial printer drivers.
  68.  
  69.  
  70. abs0    segment at 0        ; this is where the interrupt vectors live
  71.  
  72.     org    50h        ; int 14h - rs232 io handler vector
  73. com_off dw    ?
  74. com_seg dw    ?
  75.  
  76.     org    180h        ; int 60h - user-definable (so I used it!)
  77. int60_o dw    ?
  78. int60_s dw    ?
  79.  
  80. abs0    ends
  81.  
  82. code segment
  83.  
  84.     assume cs:code, ds:abs0
  85.  
  86.     org    100h
  87.  
  88. main proc far    ; set up pointers to intercept calls to rs232 handler
  89.         ;  and arrange for this piece of code to remain in memory
  90.         ;   forever after.
  91.  
  92.     xor    ax,ax        ; ds := absolute 0 segment
  93.     mov    ds,ax
  94.     mov    ax,com_off    ; copy rs232 vectors to int 60h
  95.     mov    int60_o,ax
  96.     mov    ax,com_seg
  97.     mov    int60_s,ax
  98.     cli            ; copy pointer to new handler to int 14h
  99.     mov    com_off,offset intercept
  100.     mov    ax,cs
  101.     mov    com_seg,ax
  102.     sti
  103.     mov    dx,offset next_byte    ; point to end of program
  104.     int    27h        ; terminate but stay resident
  105.  
  106.  
  107. id_code db    "FLOWCNTL V1.0 Bruce Walker 1984"
  108. flag    db    'Q'-40h         ; ^S means stop - ^Q means go again
  109.  
  110. ; Whenever someone calls the rs232 (int 14h) handler now, we intercept and
  111. ; if the call was a "test serial line status"-type (command code 3 in AH),
  112. ; check for control-S / control-Q handshaking from the serial device.  We
  113. ; translate the serial handshake into a "fake" CTS bit in the status register
  114. ; by setting or resetting the CTS status bit in AH as appropriate, and passing
  115. ; it back to the calling program.
  116.  
  117. intercept:
  118.     sti
  119.     push    ds
  120.     push    cs        ; set data seg to current code segment
  121.     pop    ds
  122.  
  123.     assume ds:code
  124.  
  125.     or    dx,dx        ; we only twiddle com1
  126.     jz    com1
  127. let_em_go:
  128.     int    60h        ; let call thru unaltered
  129. beat_it:
  130.     pop    ds
  131.     iret
  132.  
  133. com1:
  134.     cmp    ah,3        ; status call?
  135.     jne    let_em_go
  136.     int    60h        ; get status bytes into ax
  137.     push    ax
  138.     and    ah,01h        ; any rx'ed chars?
  139.     jz    c3
  140.     mov    ah,2        ; rx
  141.     int    60h
  142.     cmp    al,'S'-40h
  143.     je    c2
  144.     cmp    al,'Q'-40h
  145.     jne    c3
  146. c2:
  147.     mov    byte ptr flag,al
  148. c3:
  149.     cmp    flag,'S'-40h
  150.     pop    ax
  151.     jne    c4
  152.     and    al,10h        ; CTS low
  153.     jmp    beat_it
  154. c4:
  155.     or    al,10h        ; CTS high
  156.     jmp    beat_it
  157.  
  158. next_byte:
  159.  
  160. main    endp
  161.  
  162. code ends
  163.  
  164.     end    main
  165.